<script setup>

// 事件总线 - 处理信号发布和监听
class EventBus {
    constructor() {
        this.listeners = new Map();
    }
    
    // 监听信号
    on(signalName, callback) {
        if (!this.listeners.has(signalName)) {
            this.listeners.set(signalName, []);
        }
        this.listeners.get(signalName).push(callback);
        return () => this.off(signalName, callback); // 返回取消监听函数
    }
    
    // 取消监听
    off(signalName, callback) {
        if (!this.listeners.has(signalName)) return;
        const callbacks = this.listeners.get(signalName);
        const index = callbacks.indexOf(callback);
        if (index !== -1) callbacks.splice(index, 1);
    }
    
    // 发布信号
    emit(signalName, payload) {
        console.log(`信号 ${signalName} 已发出`,"this is ",this);
        if (!this.listeners.has(signalName)) return;
        this.listeners.get(signalName).forEach(callback => callback(payload));
    }
}

// Servo 类 - 控制一组关节
class Servo {
    constructor(name,eventBus) {
        this.name = name;
        this.eventBus = eventBus; 
        this.jointPositions = new Map();
        console.log(`初始化 ${this.name} 控制器`);
    }
    
    // 初始化关节位置
    initializeJoint(jointId, initialPosition = 0) {
        this.jointPositions.set(jointId, initialPosition);
        console.log(`${this.name} 关节 ${jointId} 初始位置: ${initialPosition}`);
    }
    
    // 获取关节当前位置
    getJointPosition(jointId) {
        return this.jointPositions.get(jointId) || 0;
    }
    
    // 设置关节位置（内部使用）
    _setJointPosition(jointId, position) {
        this.jointPositions.set(jointId, position);
        console.log(`${this.name} 关节 ${jointId} 当前位置: ${position.toFixed(2)}`);
    }
    
    // 平滑移动单个关节到目标位置
    moveJoint(jointId, targetPosition, duration = 20000) {
        return new Promise((resolve) => {
            const startTime = performance.now();
            const startPosition = this.getJointPosition(jointId);
            const distance = targetPosition - startPosition;
            
            const animate = (currentTime) => {
                const elapsedTime = currentTime - startTime;
                const progress = Math.min(elapsedTime / duration, 1);
                const easeOutCubic = 1 - Math.pow(1 - progress, 3);
                const currentPosition = startPosition + distance * easeOutCubic;
                
                this._setJointPosition(jointId, currentPosition);
                
                if (progress < 1) {
                    requestAnimationFrame(animate);
                } else {
                    console.log(`${this.name} 关节 ${jointId} 已到达目标: ${targetPosition}`);
                    resolve();
                }
            };
            
            requestAnimationFrame(animate);
        });
    }
    
    // 同时移动多个关节
    moveJoints(jointParamsArray) {
        const promises = jointParamsArray.map(({ jointId, targetPosition, duration }) => {
            return this.moveJoint(jointId, targetPosition, duration);
        });
        
        return Promise.all(promises);
    }

    setJointParamArray(jointParamsArray) {
        this.jointParamsArray = jointParamsArray; 
    }

    async move(){
        return this.moveJoints(this.jointParamsArray);
    }
    onStart(){
        // 初始化各控制器的关节// 初始化各控制器的关节
        this.initializeJoint(1, 0);  // 机械臂关节1
        this.initializeJoint(2, 0);  // 机械臂关节2
    }
    async onRun(){
        // get target position
        await this.move(); 
        console.log("控制器的关节运动已完成,发送到位信号!");
        this.eventBus.emit('jointPositionArrived', this.jointParamsArray);
        return Promise.resolve();
    }
}

// 使用示例
async function simulateMultiServoMovement() {


    const eventBus = new EventBus();
    // 创建多个 Servo 控制器
    const armServo = new Servo("机械臂",eventBus);
    armServo.onStart();
    armServo.setJointParamArray(
        [
        { jointId: 1, targetPosition: 90, duration: 500 }, 
        { jointId: 2, targetPosition: 45, duration: 500 }
        ]
    );
    const gripperServo = new Servo("夹爪",eventBus);
    gripperServo.onStart();
       
    try {
        console.log("开始多控制器协同运动...");
        eventBus.on('jointPositionArrived', (jointParamsArray) => {
            console.log("收到关节位置到达信号:", jointParamsArray);
            // 处理接收到的信号，例如更新其他控制器的状态
            gripperServo.moveJoint(1, 30, 500);
            console.log("所有控制器的关节运动已完成!");
        });

        await armServo.onRun(); 
        
        console.log("ArmServo 的关节运动已完成!");
        
    } catch (error) {
        console.error("运动过程中出错:", error);
    }
}

// 启动多控制器仿真
simulateMultiServoMovement();    

</script>

<template>
  <div ref="container">
  
  </div>


</template>

<style scoped>
  div {
    width: 100%;
    height: 100vh;
    margin: 0;
    padding: 0;
    /* overflow: hidden; */
  }
</style>
